package com.chenyaowei.happyhub.security;

import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.chenyaowei.happyhub.excepiton.BasicException;
import com.chenyaowei.happyhub.excepiton.ExceptionEnum;
import com.chenyaowei.happyhub.pojo.wechatuser.Account;
import com.chenyaowei.happyhub.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Component;


/**
 * 真正执行认证逻辑的manager, {@link WxAppletAuthenticationFilter}会将认证委托给{@link WxAppletAuthenticationManager}来做
 * @author tanwubo
 */
@Component
@Slf4j
public class WxAppletAuthenticationManager implements AuthenticationManager {
    @Autowired
    private AuthService authService;
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        WxAppletAuthenticationToken wxAppletAuthenticationToken = null;
        if (authentication instanceof WxAppletAuthenticationToken) {
            wxAppletAuthenticationToken = (WxAppletAuthenticationToken) authentication;
        }
        Account account = authService.selectAccountByOpenid(wxAppletAuthenticationToken.getOpenid());
        //执行注册逻辑
        if (account == null) {
            log.debug("account not exist, began to register. openid is [{}]", wxAppletAuthenticationToken.getOpenid());
            //签名校验
            Digester digester = new Digester(DigestAlgorithm.SHA1);
            String data = wxAppletAuthenticationToken.getRawData() + wxAppletAuthenticationToken.getSessionKey();
            String signature = digester.digestHex(data);
            if (!wxAppletAuthenticationToken.getSignature().equals(signature)) {
                log.error("signature is invalid, [{}] vs [{}]", signature, wxAppletAuthenticationToken.getSignature());
                throw new BasicException(ExceptionEnum.SIGN_INVALID.customMessage("signature is invalid, [%s] vs [%s]", signature, wxAppletAuthenticationToken.getSignature()));
            }
            //获取用户信息
            ObjectMapper mapper=new ObjectMapper();
            try {
                account = mapper.readValue(wxAppletAuthenticationToken.getRawData(),Account.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            account.setOpenid(wxAppletAuthenticationToken.getOpenid());
            account.setSessionKey(wxAppletAuthenticationToken.getSessionKey());
            account.setRole("ROLE_USER");
            authService.register(account);
            //获取权限
            return new WxAppletAuthenticationToken(account.getOpenid(), account.getSessionKey(), AuthorityUtils.createAuthorityList(account.getRole()));
        }
        // 存在：获取权限
        return new WxAppletAuthenticationToken(wxAppletAuthenticationToken.getOpenid(), wxAppletAuthenticationToken.getSessionKey(), AuthorityUtils.createAuthorityList(account.getRole()));
    }

}
